﻿//////////////////////////////////////////////////////////////////////////////
//
//  Copyright © 1998-2024 Glodon Company Limited.  All rights reserved.
//
//  Use of this software is subject to the terms of the Glodon license
//  agreement provided at the time of installation or download, or which
//  otherwise accompanies this software in either electronic or hard copy form.  
//
//////////////////////////////////////////////////////////////////////////////


#pragma once
#include "IGraphicsNode.h"
#include "Coordinate3d.h"

namespace gcmp
{   
    class Intervald;
    class IPlane;

    /// \brief 平面图形节点
    class GCMP_GRAPHICS_NODE_INTERFACE_EXPORT IGraphicsPlane : public IGraphicsNode
    {
        DEFINE_CAST_DERIVED(IGraphicsPlane, IGraphicsNode)

    public:
        /// \brief 析构器
        virtual ~IGraphicsPlane();

    public:

        /// \brief 设置平面UV范围
        /// \param uMin U向最小值
        /// \param uMax U向最大值
        /// \param vMin V向最小值
        /// \param vMax V向最大值
        /// \return true-设置成功；false-设置失败(当uMinimum大于uMaximum，或者vMinimum大于vMaximum时)
        virtual bool SetPlaneRanges(double uMin, double uMax, double vMin, double vMax) = 0;

        /// \brief 获取平面的三维坐标系
        /// \return 平面的三维坐标系
        virtual Coordinate3d GetCoordinate() const = 0;

        /// \brief 获取平面坐标系原点的空间位置
        /// \return 平面坐标系原点的空间位置
        virtual Vector3d GetOrigin() const = 0;

        /// \brief 获取平面U向的向量
        /// \return 平面U向的向量
        virtual Vector3d GetDirectionU() const = 0;

        /// \brief 获取平面V向的向量
        /// \return 平面V向的向量
        virtual Vector3d GetDirectionV() const = 0;

        /// \brief 获取平面法向量
        /// \return 平面法向量
        virtual Vector3d GetNormal() const = 0;

        /// \brief 设置平面坐标系原点的空间位置
        /// \param origin 平面坐标系原点的空间位置
        /// \return 无    
        virtual void SetOrigin(const Vector3d& origin) = 0;

        /// \brief 获取U向起点参数值
        /// \return U向起点参数值
        virtual double GetStartU() const = 0;

        /// \brief 获取V向起点参数值
        /// \return V向起点参数值
        virtual double GetStartV() const = 0;

        /// \brief 获取U向终点参数值
        /// \return U向终点参数值
        virtual double GetEndU() const = 0;

        /// \brief 获取V向终点参数值
        /// \return V向终点参数值
        virtual double GetEndV() const = 0;

        /// \brief 获取U向参数范围
        /// \return U向参数范围
        virtual Intervald GetRangeU() const = 0;

        /// \brief 获取V向参数范围
        /// \return V向参数范围
        virtual Intervald GetRangeV() const = 0;

        /// \brief 设置UV向参数范围
        /// \param rangeU U向参数范围
        /// \param rangeV V向参数范围
        /// \return 无    
        virtual void SetLimits(const Intervald& rangeU, const Intervald& rangeV) = 0;

        /// \brief 获取给定点的UV参数值
        /// \param Point 给定点
        /// \param dU U向参数值
        /// \param dV V向参数值
        /// \return 无    
        virtual void GetParameter(const Vector3d& Point, double& dU, double& dV) const = 0;

        /// \brief 根据给定点的UV参数值获取空间点
        /// \param dU U向参数值
        /// \param dV V向参数值
        /// \return 空间点    
        virtual Vector3d GetPoint(double dU, double dV) const = 0;

        /// \brief 对平面进行反向
        /// \return 无
        virtual void Negate() = 0;

        /// \brief 获取平面
        /// \return 平面
        virtual const IPlane* GetGmIPlane() const = 0;

        /// \brief 获取调试信息
        /// \return 调试信息
        virtual std::wstring GetStringForDebug() const = 0;

        /// \brief 平面初始化设置
        /// \param origin 原点
        /// \param normal 法向量
        /// \param intervalU U向范围
        /// \param intervalV V向范围
        /// \return true-设置成功；false-设置失败
        virtual bool Initialize( const Vector3d& origin,const Vector3d& normal, const Intervald& intervalU, const Intervald& intervalV) = 0;

        /// \brief 平面初始化设置
        /// \param origin 原点
        /// \param uDirection U方向向量
        /// \param vDirection V方向向量
        /// \param intervalU U向范围
        /// \param intervalV V向范围
        /// \return true-设置成功；false-设置失败
        virtual bool Initialize( const Vector3d& origin,const Vector3d& uDirection, const Vector3d& vDirection,
            const Intervald& intervalU, const Intervald& intervalV) = 0;

    public:
        /// \brief 创建一个默认的平面图形节点
        /// \return 平面图形节点
        static OwnerPtr<IGraphicsPlane> Create();

        /// \brief 通过[原点][法向量]创建一个平面图形节点
        /// \param origin 原点
        /// \param normal 法向量
        /// \return 平面图形节点(如果创建失败则返回空)
        static OwnerPtr<IGraphicsPlane> CreateByNormal(const Vector3d& origin, const Vector3d& normal);

        /// \brief 通过[原点][U向量][V向量]创建一个平面图形节点
        /// \param origin 原点
        /// \param uDirection U方向向量
        /// \param vDirection V方向向量
        /// \return 平面图形节点(如果创建失败则返回空)
        static OwnerPtr<IGraphicsPlane> CreateByDirections(const Vector3d& origin, const Vector3d& uDirection, const Vector3d& vDirection);
    };
}

